home *** CD-ROM | disk | FTP | other *** search
- (*******************************************************************
-
- DRVR.pas
-
- Transfer DA source.
-
- (c) 1988, by Clifford Story & Attic Software
-
- *******************************************************************)
-
- unit DRVR;
-
- (******************************************************************)
-
- interface
-
- (******************************************************************)
-
- uses macintf, Common;
-
- (******************************************************************)
-
- procedure open(var device : dctlentry;
- var block : paramblockrec);
-
- procedure ctl(var device : dctlentry;
- var block : paramblockrec);
-
- procedure close(var device : dctlentry;
- var block : paramblockrec);
-
- (******************************************************************)
-
- implementation
-
- (******************************************************************)
-
- procedure killda(var device : dctlentry;
- var block : paramblockrec); external;
-
- procedure setdisk(theflag : logical); external;
- function getdisk : logical; external;
-
- (******************************************************************)
-
- procedure launch(config : integer; name : ptr); inline $204F, $A9F2;
-
- { movea.l A7,A0
- _launch }
-
- (******************************************************************)
-
- procedure callMDEF(message : integer; themenu : menuhandle;
- static menurect : rect; hitpoint : point;
- var whichitem : integer; address : ptr);
- inline $205F, $4E90;
-
- (******************************************************************)
-
- procedure centerdialog(globals : ghandle;
- thetype : ostype; theid : integer);
-
- var
- thehandle : alertthndl;
-
- begin
-
- with globals^^ do begin
-
- thehandle := alertthndl(getresource(thetype,
- resfactor + theid));
- hlock(handle(thehandle));
- with thehandle^^ do begin
-
- with boundsrect do
- setrect(boundsrect, 0, 0,
- right - left, bottom - top);
-
- with QDglobals^.screenbits.bounds,
- boundsrect.botright do
- offsetrect(boundsrect, (right - left - h) div 2,
- (bottom - top - v + 2 * menuheight) div 3);
-
- end;
- hunlock(handle(thehandle));
-
- end;
-
- end;
-
- (******************************************************************)
-
- procedure message(globals : ghandle;
- static string1, string2, string3, string4 : str255);
-
- var
- dummy : integer;
-
- begin
-
- initcursor;
- paramtext(string1, string2, string3, string4);
- centerdialog(globals, 'ALRT', messagedialog);
- dummy := alert(globals^^.resfactor + messagedialog, nil);
-
- end;
-
- (******************************************************************)
-
- procedure showscreen(globals : ghandle; theitem : integer);
-
- var
- itemname : str255;
- savedport : grafptr;
- dummy : integer;
- newport : grafport;
- thepicture : pichandle;
- therect : rect;
-
- begin
-
- with globals^^ do begin
-
- initcursor;
- getport(savedport);
- openport(@newport);
- setport(@newport);
-
- thepicture := pichandle(getresource('PICT',
- resfactor + 1000 + theitem));
- with thepicture^^.picframe do
- setrect(therect, 0, 0, right - left, bottom - top);
- with QDglobals^.screenbits.bounds, therect.botright do
- offsetrect(therect, (right - left - h) div 2,
- (bottom - top - v) div 3);
- drawpicture(thepicture, therect);
-
- repeat until button;
-
- closeport(@newport);
- drawmenubar;
- paintbehind(windowpeek(frontwindow),
- rgnhandle(longpointer(grayrgn)^));
-
- setport(savedport);
- flushevents(everyevent, 0);
-
- end;
-
- end;
-
- (******************************************************************)
-
- function diskfilter(theitem : integer;
- thedialog : dialogptr) : integer;
-
- var
- thetype : integer;
- thehandle : handle;
- therect : rect;
-
- begin
-
- if theitem = getopen then begin
- getditem(thedialog, geteject, thetype, thehandle, therect);
- setdisk(controlhandle(thehandle)^^.contrlhilite = 255);
- end;
-
- diskfilter := theitem;
-
- end;
-
- (******************************************************************)
-
- procedure newtransfer(globals : ghandle);
-
- label
- 100;
-
- var
- thepoint : point;
- thelist : sftypelist;
- thereply : sfreply;
- theblock : paramblockrec;
- anerror : integer;
- thehandle : handle;
- homedisk : integer;
- thecount : integer;
- index : integer;
-
- begin
-
- with QDglobals^.screenbits.bounds do
- setpt(thepoint, (right - left - 348) div 2,
- (bottom - top - 200
- + 2 * globals^^.menuheight) div 3);
- thelist[0] := 'APPL';
-
- sfgetfile(thepoint, '', nil, 1, thelist, @diskfilter, thereply);
-
- if thereply.good then with globals^^ do begin
-
- with theblock do begin
- iocompletion := nil;
- newappl.volume[0] := chr(0);
- ionameptr := @newappl.volume;
- if shortpointer(fsfcblen)^ < 0 then
- iovrefnum := thereply.vrefnum
- else
- iovrefnum := - shortpointer(sfsavedisk)^;
- iovolindex := 0;
- end;
- anerror := pbgetvinfo(@theblock, false);
- if anerror <> noerr then begin
- message(globals,
- 'Sorry - the transfer failed. I cou',
- 'ldn''t get the volume name.', '', '');
- choice := 0;
- goto 100;
- end;
-
- newappl.directory := longpointer(curdirstore)^;
- blockmove(@thereply.fname, @newappl.name, 32);
- choice := - 1;
-
- thehandle := getresource('MDEF', resfactor + mdefnum);
- homedisk := homeresfile(thehandle);
- if homedisk = 0 then
- homedisk := shortpointer(sysmap)^;
- anerror := getvrefnum(homedisk, homedisk);
-
- if getdisk or (theblock.iovrefnum = homedisk) then begin
-
- thecount := menudata^^.count + 1;
- menudata^^.count := thecount;
- sethandlesize(handle(menudata),
- 2 + thecount * sizeof(tline));
-
- hlock(handle(menudata));
- with menudata^^ do begin
-
- for index := 1 to thecount do
- if (iucompstring(appl[index].name,
- thereply.fname) > 0) then begin
- thecount := index;
- leave;
- end;
-
- blockmove(@appl[thecount], @appl[thecount + 1],
- gethandlesize(handle(menudata))
- - long(@appl[thecount + 1])
- + long(menudata^));
-
- blockmove(@newappl, @appl[thecount], sizeof(tline));
-
- end;
- hunlock(handle(menudata));
-
- choice := thecount;
-
- end;
-
- message(globals,
- 'Now quit to go to “', thereply.fname,
- '”.', '');
-
- 100: end;
-
- end;
-
- (******************************************************************)
-
- procedure deleteappl(globals : ghandle; theappl : integer);
-
- begin
-
- with globals^^ do begin
-
- hlock(handle(menudata));
- with menudata^^ do begin
-
- count := count - 1;
- blockmove(@appl[theappl + 1], @appl[theappl],
- gethandlesize(handle(menudata))
- - long(@appl[theappl + 1])
- + long(menudata^));
-
- end;
- hunlock(handle(menudata));
-
- sethandlesize(handle(menudata),
- gethandlesize(handle(menudata))
- - sizeof(tline));
-
- end;
-
- end;
-
- (******************************************************************)
-
- procedure dotheok(thewindow : windowptr; theitem : integer);
-
- var
- thetype : integer;
- thehandle : handle;
- therect : rect;
-
- begin
-
- getditem(thewindow, ok, thetype, thehandle, therect);
-
- pensize(3, 3);
- insetrect(therect, -4, -4);
- frameroundrect(therect, 16, 16);
- pensize(1, 1);
-
- end;
-
- (******************************************************************)
-
- procedure dothelist(thewindow : windowptr; theitem : integer);
-
- var
- thetype : integer;
- thehandle : handle;
- therect : rect;
-
- begin
-
- lupdate(thewindow^.visrgn, listhandle(getwrefcon(thewindow)));
-
- getditem(thewindow, theitem, thetype, thehandle, therect);
- insetrect(therect, - 1, - 1);
- framerect(therect);
-
- end;
-
- (******************************************************************)
-
- procedure dotheline(thewindow : windowptr; theitem : integer);
-
- var
- thetype : integer;
- thehandle : handle;
- therect : rect;
-
- begin
-
- getditem(thewindow, theitem, thetype, thehandle, therect);
-
- moveto(therect.left, therect.top);
- lineto(therect.right, therect.top);
-
- end;
-
- (******************************************************************)
-
- function editfilter(thedialog : dialogptr;
- var theevent : eventrecord;
- var theitem : integer): logical;
-
- var
- thekey : integer;
- thepoint : point;
- thetype : integer;
- thehandle : handle;
- therect : rect;
-
- begin
-
- editfilter := false;
-
- if theevent.what = keydown then begin
-
- thekey := bitand(charcodemask, theevent.message);
- if (thekey = enterkey) or (thekey = returnkey) then begin
- theitem := ok;
- editfilter := true;
- end else if thekey = periodkey then begin
- theitem := cancel;
- editfilter := true;
- end else if (thekey = ord('d')) or (thekey = ord('D')) then begin
- theitem := editdelete;
- editfilter := true;
- end;
-
- end else if theevent.what = mousedown then begin
-
- thepoint := theevent.where;
-
- globaltolocal(thepoint);
- getditem(thedialog, editlist, thetype, thehandle, therect);
-
- if ptinrect(thepoint, therect) then begin
- editfilter := true;
- if lclick(thepoint, 0, listhandle(getwrefcon(thedialog))) then
- ;
- theitem := editlist;
- end;
-
- end;
-
- end;
-
- (******************************************************************)
-
- procedure edittransfer(globals : ghandle);
-
- var
- savedport : grafptr;
- thedialog : dialogptr;
- therecord : dialogrecord;
- thetype : integer;
- thehandle : handle;
- therect : rect;
- bounds : rect;
- thepoint : point;
- thelist : listhandle;
- response : integer;
-
- begin
-
- thehandle := getresource('PACK', 0);
- if thehandle = nil then
- message(globals,
- 'Sorry - You will need System 3.0 or ',
- 'later to edit the menu. You can era',
- 'se the entire menu by dragging the T',
- 'ransfer Data file to the Trash.')
- else with globals^^ do begin
-
- getport(savedport);
- centerdialog(globals, 'DLOG', editdialog);
- thedialog := getnewdialog(resfactor + editdialog,
- @therecord, pointer(-1));
- setport(thedialog);
-
- getditem(thedialog, themask, thetype, thehandle, therect);
- thehandle := handle(@dotheok);
- setditem(thedialog, themask, useritem, thehandle, therect);
-
- getditem(thedialog, editlist, thetype, thehandle, therect);
- thehandle := handle(@dothelist);
- setditem(thedialog, editlist, useritem, thehandle, therect);
-
- therect.right := therect.right - 15;
- setrect(bounds, 0, 0, 1, menudata^^.count);
- setpt(thepoint, therect.right - therect.left, 16);
- thelist := lnew(therect, bounds, thepoint,
- resfactor + ldefnum, thedialog,
- true, false, false, true);
- thelist^^.refcon := long(menudata);
- setwrefcon(thedialog, long(thelist));
-
- getditem(thedialog, editline, thetype, thehandle, therect);
- thehandle := handle(@dotheline);
- setditem(thedialog, editline, useritem, thehandle, therect);
-
- showwindow(thedialog);
-
- thehandle := handle(menudata);
- response := handtohand(thehandle);
-
- repeat
-
- modaldialog(@editfilter, response);
-
- if response = editdelete then begin
- setpt(thepoint, 0, 0);
- if lgetselect(true, thepoint, thelist) then begin
- deleteappl(globals, thepoint.v + 1);
- ldelrow(1, thepoint.v, thelist);
- end;
- end;
-
- until (response = ok) or (response = cancel);
-
- if response = ok then begin
- calcmenusize(themenu);
- message(globals,
- 'This cancels any earlier choice ',
- 'from the menu.', '', '');
- choice := 0;
- disposhandle(thehandle);
- end else begin
- disposhandle(handle(menudata));
- menudata := thandle(thehandle);
- thehandle := themenu^^.menuproc;
- hlock(thehandle);
- callMDEF(msethandle, themenu, therect,
- point(menudata), thetype, thehandle^);
- hunlock(thehandle);
- end;
-
- ldispose(thelist);
- closedialog(thedialog);
- setport(savedport);
-
- end;
-
- end;
-
- (******************************************************************)
-
- procedure dofinder(globals : ghandle);
-
- var
- thecount : integer;
-
- begin
-
- globals^^.choice := 0;
- message(globals,
- 'Now quit to go to the Finder',
- '', '', '');
-
- end;
-
- (******************************************************************)
-
- procedure clickmenu(globals : ghandle; theitem : integer);
-
- var
- thecount : integer;
-
- begin
-
- case theitem of
- aboutitem : showscreen(globals, theitem);
- atticitem : showscreen(globals, theitem);
- transitem : newtransfer(globals);
- edititem : edittransfer(globals);
- finderitem : dofinder(globals);
- otherwise
- with globals^^ do begin
- choice := theitem - 7;
- blockmove(@menudata^^.appl[choice], @newappl, sizeof(tline));
- message(globals,
- 'Now quit to go to your choice',
- '', '', '');
- end;
- end;
-
- end;
-
- (******************************************************************)
-
- procedure getdata(theresource : handle; var thedata : thandle;
- var thevolume : integer; var thefile : integer);
-
- label
- 100;
-
- var
- homedisk : integer;
- theblock : mixedblock;
- anerror : integer;
- thesize : long;
-
- begin
-
- thedata := nil;
-
- thevolume := homeresfile(theresource);
- if thevolume = 0 then
- thevolume := shortpointer(sysmap)^;
- if getvrefnum(thevolume, thevolume) <> noerr then
- goto 100;
-
- if shortpointer(fsfcblen)^ < 0 then
- homedisk := thevolume
- else begin
-
- with theblock.hfsblock do begin
- iocompletion := nil;
- ionameptr := nil;
- iovrefnum := thevolume;
- iovolindex := 0;
- end;
- if pbhgetvinfo(@theblock, false) <> noerr then
- goto 100;
-
- with theblock.dirblock do begin
- iowddirid := theblock.hfsblock.iovfndrinfo[1];
- iowdprocid := procid;
- end;
- if pbopenwd(@theblock, false) <> noerr then
- goto 100;
-
- homedisk := theblock.dirblock.iovrefnum;
-
- end;
-
- anerror := fsopen('Transfer Data', homedisk, thefile);
- if anerror <> noerr then begin
-
- if anerror <> fnferr then
- goto 100;
-
- anerror := create('Transfer Data', homedisk, '....', '....');
- if anerror <> noerr then
- goto 100;
-
- anerror := fsopen('Transfer Data', homedisk, thefile);
- if anerror <> noerr then
- goto 100;
-
- thedata := thandle(newhandle(2));
- if thedata <> nil then
- thedata^^.count := 0;
- goto 100;
-
- end;
-
- anerror := geteof(thefile, thesize);
- if anerror <> noerr then begin
- anerror := fsclose(thefile);
- goto 100;
- end;
-
- thedata := thandle(newhandle(thesize));
- if thedata = nil then begin
- anerror := fsclose(thefile);
- goto 100;
- end;
-
- hlock(handle(thedata));
- anerror := fsread(thefile, thesize, ptr(thedata^));
- if anerror <> noerr then begin
- disposhandle(handle(thedata));
- thedata := nil;
- anerror := fsclose(thefile);
- end;
-
- if thedata <> nil then
- hunlock(handle(thedata));
-
- 100: end;
-
- (******************************************************************)
-
- procedure setdata(globals : ghandle);
-
- var
- thesize : long;
- anerror : integer;
-
- begin
-
- with globals^^ do begin
-
- hlock(handle(menudata));
- thesize := 2 + menudata^^.count * sizeof(tline);
- anerror := setfpos(menufile, fsfromstart, 0);
- anerror := fswrite(menufile, thesize, ptr(menudata^));
- anerror := seteof(menufile, thesize);
- anerror := fsclose(menufile);
- anerror := flushvol(nil, menudisk);
- hunlock(handle(menudata));
-
- end;
-
- end;
-
- (******************************************************************)
-
- procedure transferappl(globals : ghandle;
- var device : dctlentry;
- var block : paramblockrec);
-
- label
- 100;
-
- var
- thesize : long;
- anerror : integer;
- thelength : integer;
- thestring : str255;
- theblock : mixedblock;
- theinfo : finfo;
- thehandle : handle;
- therect : rect;
- theitem : integer;
-
- begin
-
- setdata(globals);
-
- if globals^^.choice <> 0 then with globals^^, newappl do begin
-
- thelength := ord(volume[0]) + 1;
- blockmove(@volume, @thestring, thelength);
- thestring[0] := chr(thelength);
- thestring[thelength] := ':';
-
- with theblock.volblock do begin
- iocompletion := nil;
- ionameptr := @thestring;
- iovolindex := - 1;
- end;
- anerror := pbgetvinfo(@theblock, false);
- if anerror <> noerr then
- goto 100;
-
- blockmove(@name, @thestring, 32);
-
- if shortpointer(fsfcblen)^ = -1 then
- anerror := setvol(nil, theblock.volblock.iovrefnum)
- else with theblock.dirblock do begin
-
- iocompletion := nil;
- ionameptr := nil;
- iovrefnum := theblock.volblock.iovrefnum;
- iowdprocid := procid;
- iowddirid := directory;
- anerror := pbopenwd(@theblock, false);
-
- if anerror = noerr then
- anerror := setvol(nil, iovrefnum)
-
- end;
-
- if anerror = noerr then begin
- anerror := getfinfo(thestring, 0, theinfo);
- if (anerror = noerr) and (theinfo.fdtype = 'APPL') then begin
- killda(device, block);
- launch(0, @thestring);
- end;
- end;
-
- 100: getdata(themenu^^.menuproc, menudata, menudisk, menufile);
- if menudata <> nil then begin
- deleteappl(globals, choice);
- setdata(globals);
- end;
-
- message(globals,
- 'I can''t find “', thestring,
- '”. Returning to the Finder.', '');
-
- end;
-
- end;
-
- (******************************************************************)
-
- procedure open(var device : dctlentry;
- var block : paramblockrec);
-
- label
- 100;
-
- var
- globals : ghandle;
- thehandle : handle;
- therect : rect;
- theitem : integer;
-
- begin
-
- if device.dctldelay <> 0 then begin
- sysbeep(10);
- goto 100;
- end;
-
- globals := ghandle(newhandle(sizeof(grecord)));
- if globals = nil then begin
- sysbeep(10);
- goto 100;
- end;
-
- hlock(handle(globals));
- with globals^^ do begin
-
- unitnumber := device.dctlrefnum;
- resfactor := $BFE0 - 32 * unitnumber - 1000;
-
- if bittst(ptr(rom85), 0) then
- menuheight := 20
- else
- menuheight := shortpointer(mbarheight)^;
-
- if getresource('PACK', 0) <> nil then begin
- if (ngettrapaddress($A88F, tooltrap)
- <> ngettrapaddress($A89F, tooltrap)) then begin
- message(globals, 'Sorry, the Transfer DA doesn''t ',
- 'work under the Multifinder.', '', '');
- killda(device, block);
- goto 100;
- end;
- end;
-
- themenu := getmenu(resfactor + menunum);
- thehandle := getresource('MDEF', resfactor + mdefnum);
- themenu^^.menuproc := thehandle;
- getdata(thehandle, menudata, menudisk, menufile);
- if menudata = nil then begin
- message(globals,
- 'Sorry - Failed to read the “Transfer ',
- 'Data” file.', '', '');
- disposhandle(handle(globals));
- killda(device, block);
- goto 100;
- end;
-
- hlock(thehandle);
- callMDEF(msethandle, themenu, therect,
- point(menudata), theitem, thehandle^);
- hunlock(thehandle);
-
- insertmenu(themenu, 0);
- calcmenusize(themenu);
- drawmenubar;
-
- choice := 0;
-
- device.dctlmenu := resfactor + menunum;
- device.dctlstorage := handle(globals);
- device.dctldelay := 32000;
-
- end;
- hunlock(handle(globals));
-
- 100: end;
-
- (******************************************************************)
-
- procedure ctl(var device : dctlentry;
- var block : paramblockrec);
-
- label
- 100;
-
- var
- globals : ghandle;
-
- begin
-
- if device.dctldelay < 32000 then
- goto 100;
-
- device.dctldelay := 31000;
- globals := ghandle(device.dctlstorage);
-
- hlock(handle(globals));
- if block.cscode = accmenu then
- clickmenu(globals, block.csparam[1])
- else if block.cscode = -1 then
- transferappl(globals, device, block);
- hunlock(handle(globals));
-
- device.dctldelay := 32000;
-
- 100: end;
-
- (******************************************************************)
-
- procedure close(var device : dctlentry;
- var block : paramblockrec);
-
- var
- globals : ghandle;
-
- begin
-
- if device.dctldelay = 32000 then begin
- globals := ghandle(device.dctlstorage);
- hlock(handle(globals));
- transferappl(globals, device, block);
- end;
-
- end;
-
- (******************************************************************)
-
- end.
-
- (******************************************************************)
-